using System;
using Microsoft.Xna.Framework;

namespace Xfinity.AI.Entities
{
    /// <summary>
    /// A generic trigger.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Trigger<T> : LogicalEntity
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Trigger&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="conditions">The conditions.</param>
        /// <param name="name">The name.</param>
        /// <param name="game">The game.</param>
        public Trigger(T conditions, string name, Game game)
            : base(name, game)
        {
            this.conditions = conditions;
        }
        private T conditions;

        /// <summary>
        /// Gets or sets the conditions on which to trigger.
        /// </summary>
        /// <value>The conditions.</value>
        public T Conditions
        {
            get { return conditions; }
            set { conditions = value; }
        }

        private bool triggered;

        /// <summary>
        /// Gets a value indicating whether this <see cref="Trigger&lt;T&gt;"/> is triggered.
        /// </summary>
        /// <value><c>true</c> if triggered; otherwise, <c>false</c>.</value>
        public bool Triggered
        {
            get { return triggered; }
        }
        private T current;

        /// <summary>
        /// Gets or sets the current value.
        /// </summary>
        /// <value>The current value.</value>
        public T Current
        {
            get { return current; }
            set { current = value; }
        }

        /// <summary>
        /// Determine wether or not to fire. This function must be overrided for non-precise conditions.
        /// </summary>
        /// <returns>A Boolean value indicating wether or not the conditions have been met.</returns>
        protected virtual bool CheckForConditions()
        {
            if (current.Equals(conditions))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Called when the GameComponent needs to be updated.  Override this method with component-specific update code.
        /// </summary>
        /// <param name="gameTime">Time elapsed since the last call to Microsoft.Xna.Framework.GameComponent.Update(Microsoft.Xna.Framework.GameTime)</param>
        public override void Update(GameTime gameTime)
        {
            if (CheckForConditions())
            {
                if (Triggering != null)
                {
                    Triggering(this, new TriggerEventArgs(current));
                }
                triggered = true;
                ModifyEnabledFromFired();
            }
            base.Update(gameTime);
        }

        /// <summary>
        /// This function must modify the Enabled value, based on wether or not the trigger occurs once or multiple times.
        /// </summary>
        protected virtual void ModifyEnabledFromFired()
        {
            Enabled = false;
        }

        /// <summary>
        /// Called when triggered.
        /// </summary>
        public event EventHandler<TriggerEventArgs> Triggering;
    }





    public class TriggerEventArgs : EventArgs
    {
        public TriggerEventArgs(object data)
        {
            this.data = data;
        }
        private object data;

        public object Data
        {
            get { return data; }
            set { data = value; }
        }

    }
}